import 'dart:io';

import 'package:bike_ride/model/version/notification.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:path_provider/path_provider.dart';

///安装包下载工具类
typedef OnDownloadProgress = Function(int received, int total);
class VersionUtil {
  static final VersionUtil _singleton = VersionUtil._init();

  static final Dio _dio = Dio();

  List<OnDownloadProgress> listeners = [];

  bool isDownload = false;
  bool isBackgroundDownload = false;
  static late NotificationUtils notification;

  factory VersionUtil() {
    //通知栏
    notification = NotificationUtils();
    notification.init();
    return _singleton;
  }

  VersionUtil._init();


  ///[fileName] 最内层文件名字，例如download、xxx.apk
  static Future<String?> getAndroidDownloadPath({String fileName = 'Download'})async{
    Directory? storageDir = await getExternalStorageDirectory();
    if(storageDir==null)return null;
    StringBuffer sb = StringBuffer(storageDir.path);
    sb.write("/$fileName");
    return sb.toString();
  }

  ///[urlPath] 下载地址
  ///[installPathCallBack] string 文件系统apk安装位置
  void downloadApk(String urlPath,  ValueChanged installPathCallBack,bool forceUpdate) async {
    if (isDownload == true || urlPath.isEmpty) return;
    try {
      final String? apkDirPath= await getAndroidDownloadPath();
      if(apkDirPath == null) throw Exception('ExternalStorageDirectory cannot receive');
      print("安装包下载目录: $apkDirPath");
      final Directory? apkDir = createDirSync(apkDirPath);
      if(apkDir == null) throw Exception('createDirSync filed');

      String apkName = getFileName(urlPath);
      String apkPath = '$apkDirPath/$apkName';
      String apkTempPath = '$apkDirPath/temp_$apkName';

      print("安装包下载路径: $apkPath");//storage/emulated/0/Android/data/net.sharebike.lexiang.manage.app/files/Download/乐享运维-1.0.79.apk
      print("安装包下载临时存储: $apkTempPath");

      File file = File(apkPath);
      //文件系统已存在安装包
      if (file.existsSync() && !forceUpdate) {
        installPathCallBack(apkPath);
        isDownload = false;
        for (var listener in listeners) {
          listener(1, 1);
        }
        return;
      }
      isDownload = true;
      await _dio.download(
        urlPath,
        apkTempPath,
        onReceiveProgress: (int count, int total) {
          //LogUtils.e("onReceiveProgress total: $total, count: $count, prect: ${count / total}");
          for (var listener in listeners) {
            listener(count, total);
          }
          notification.showDownloadProgressNotification(((count / total) * 100).toInt());

          if (count == total) {
            isDownload = false;
            File file = File(apkTempPath);
            File fileNew = file.copySync(apkPath);
            file.deleteSync();
            if(isBackgroundDownload){
              EasyLoading.showSuccess('应用下载已完成，请开始安装');
              Future.delayed(const Duration(milliseconds: 1500),(){
                installPathCallBack(apkPath);
              });
            }else{
              installPathCallBack(apkPath);
            }
          }
        },
      );
    } catch (e) {
      print("download apk error: ${e?.toString()}");
      isDownload = false;
      for (var listener in listeners) {
        listener(-1, 1);
      }
    }
  }

  void addListener(OnDownloadProgress listener) {
    if (!listeners.contains(listener)) {
      listeners.add(listener);
    }
  }

  void removeListener(OnDownloadProgress listener) {
    if (listeners.contains(listener)) {
      listeners.remove(listener);
    }
  }

  ///安装包文件名
  static String getFileName(String urlPath) {
    if (urlPath.isEmpty) return '';
    List<String> listStr = urlPath.split("/");
    String name = listStr[listStr.length - 1];
    return name;
  }

  /// 同步创建文件夹
  static Directory? createDirSync(String? path) {
    if (path == null) return null;
    Directory dir = Directory(path);
    if (!dir.existsSync()) {
      dir.createSync(recursive: true);
    }
    return dir;
  }
}
